#ifndef AST_DECLARATIONS_DIRECT_DECLARATOR_H
#define AST_DECLARATIONS_DIRECT_DECLARATOR_H

#include "../ASTNode.h"

class sym;
class Declarator;
class TypeQualifierList;
class AssignmentExpr;
class ParameterTypeList;
class IdentifierList;
/*
C99  6.7.5
direct-declarator:
		identifier
		(   declarator   )
		direct-declarator   [   type-qualifier-list(opt)   assignment-expression(opt)   ]
		direct-declarator   [   static   type_qualifier-list(opt)   assignment-expression   ]
		direct-declarator   [   type-qualifier-list   static   assignment-expression   ]
		direct-declarator   [   type-qualifier-list(opt)   *   ]
		direct-declarator   (   parameter-type-list   )
		direct-declarator   (   idenfifier-list(opt)   )
*/
class DirectDeclarator : public ASTNode
{
public:
	enum{
		identifier,
		declarator,
		declare_arry,
		func_with_param,
		func_with_identifier
	};
protected:
	DirectDeclarator(void)
		: ASTNode(ASTNode::direct_declarator){};
public:
	DirectDeclarator(sym *pId)
		: ASTNode(ASTNode::direct_declarator)
		, m_iType(identifier)
		, m_pIdentifier( pId){};
	DirectDeclarator(Declarator *pDecl)
		: ASTNode(ASTNode::direct_declarator)
		, m_iType(declarator)
		, m_pDecl(pDecl){};
	DirectDeclarator(DirectDeclarator *pDeclarator, TypeQualifierList *pTQualList = NULL, AssignmentExpr *pAssignExpr= NULL) 
		: ASTNode(ASTNode::direct_declarator)
		, m_iType(declare_arry)
		, m_pDeclarator(pDeclarator)
		, m_pTQualList(pTQualList)
		, m_pAssignExpr(pAssignExpr) {};
	DirectDeclarator(DirectDeclarator *pDeclarator,ParameterTypeList *pParams)
		: ASTNode(ASTNode::direct_declarator)
		, m_iType(func_with_param)
		, m_pParams(pParams)
		, m_pDeclarator(pDeclarator){};

	DirectDeclarator(DirectDeclarator *pDeclarator,IdentifierList *pIdList)
		: ASTNode(ASTNode::direct_declarator)
		, m_iType(func_with_identifier)
		, m_pDeclarator(pDeclarator)
		, m_pIdList(pIdList){};

	virtual ~DirectDeclarator(void);

	virtual void									codeGen();
protected:
	tiny_int							m_iType;
	union{	//may be NULL
		sym *					m_pIdentifier;
		Declarator *			m_pDecl;
		struct {
			DirectDeclarator *  m_pDeclarator;

		struct{
			TypeQualifierList * m_pTQualList;
			AssignmentExpr *	m_pAssignExpr;
		};
		ParameterTypeList *		m_pParams;
		IdentifierList *		m_pIdList;
		};
	};
};


#endif

